package com.tianlan.blog.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.tianlan.blog.dao.SysOrganizationDao;
import com.tianlan.blog.dto.CreateOrganization;
import com.tianlan.blog.entity.SysOrganization;
import com.tianlan.blog.service.SysOrganizationService;
import com.tianlan.common.base.BusinessException;

@Service
public class SysOrganizationServiceImpl implements SysOrganizationService {

	private static final Logger log = LogManager.getLogger(SysOrganizationServiceImpl.class);

	@Autowired
	private SysOrganizationDao sysOrganizationDao;

	@Override
	public boolean createOrganization(SysOrganization organization) {
		long isCount = sysOrganizationDao.countByOrganizationNameAndOrganizationKeyAndDelFlag(
				organization.getOrganizationName(), organization.getOrganizationKey(), "0");
		if(isCount != 0){
			throw new BusinessException("组织名称或组织标识已经存在");
		}else{
			organization = sysOrganizationDao.saveAndFlush(organization);
		}
		return (organization != null && !"".equals(organization));
	}
	
	@Override
	public boolean updateOrganization(SysOrganization organization) {
		long isOrganization = sysOrganizationDao.countByIdAndDelFlag(organization.getId(), "0");
		if(isOrganization == 0){
			throw new BusinessException("组织标识已经不存在");
		}
		organization = sysOrganizationDao.save(organization);
		sysOrganizationDao.flush();
		return (organization != null && !"".equals(organization));
	}
	
	@Override
	public boolean deleteOrganization(Integer organizationId) {
        int isRemove = 0;
        if (null == organizationId)
        {
            throw new BusinessException("请选择要删除的组织");
        }
        List<SysOrganization> orgList = sysOrganizationDao.queryOrganizationTreeProc(organizationId);
        List<Integer> orgIds = new ArrayList<>();
        for (SysOrganization org: orgList)
        {
            orgIds.add(org.getId());
        }
        if (!CollectionUtils.isEmpty(orgIds))
        {
        	isRemove = sysOrganizationDao.removeByIds(orgIds);
        }
		return isRemove != 0;
	}

	@Override
	public List<SysOrganization> queryOrganizationByPanentId(Integer parentId) {
		if (null == parentId) {
			parentId = 0;
		}
		List<SysOrganization> orgs = new ArrayList<SysOrganization>();
		try {
			List<SysOrganization> orgList = sysOrganizationDao.queryOrganizationTreeProc(parentId);
			Map<Integer, SysOrganization> organizationMap = new HashMap<Integer, SysOrganization>();
			// 组装子父级目录
			for (SysOrganization organization : orgList) {
				organizationMap.put(organization.getId(), organization);
			}
			for (SysOrganization organization : orgList) {
				Integer treePId = organization.getParentId(); //子
				SysOrganization pTreev = organizationMap.get(treePId); //父-上一级
				if (null != pTreev && !organization.equals(pTreev)) {
					List<SysOrganization> nodes = pTreev.getChildren();
					if (null == nodes) {
						nodes = new ArrayList<SysOrganization>();
						pTreev.setChildren(nodes);
					}
					nodes.add(organization);
				} else {
					orgs.add(organization);
				}
			}
		} catch (Exception e) {
			log.error("查询组织树失败:", e);
			throw new BusinessException("查询组织树失败");
		}
		return orgs;
	}

	@Override
	public long checkOrganizationName(CreateOrganization org) {
		@SuppressWarnings("serial")
		Specification<SysOrganization> specification = new Specification<SysOrganization>() {
			@Override
			public Predicate toPredicate(Root<SysOrganization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				String organizationName = org.getOrganizationName();
				Predicate organizationNamePredicate = cb.equal(root.get("organizationName"), organizationName);
				Predicate delFlagPredicate = cb.equal(root.get("delFlag"), "0");
				if (null != org.getId()) {
					Predicate organizationIdPredicate = cb.notEqual(root.get("id"), org.getId());
					return cb.and(organizationNamePredicate, organizationIdPredicate, delFlagPredicate);
				}
				return cb.and(organizationNamePredicate, delFlagPredicate);
			}
		};
		return sysOrganizationDao.count(specification);
	}

	@Override
	public long checkOrganizationKey(CreateOrganization org) {
		@SuppressWarnings("serial")
		Specification<SysOrganization> specification = new Specification<SysOrganization>() {
			@Override
			public Predicate toPredicate(Root<SysOrganization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				String organizationKey = org.getOrganizationKey();
				Predicate organizationKeyPredicate = cb.equal(root.get("organizationKey"), organizationKey);
				Predicate delFlagPredicate = cb.equal(root.get("delFlag"), "0");
				if (null != org.getId()) {
					Predicate organizationIdPredicate = cb.notEqual(root.get("id"), org.getId());
					return cb.and(organizationKeyPredicate, organizationIdPredicate, delFlagPredicate);
				}
				return cb.and(organizationKeyPredicate, delFlagPredicate);
			}
		};
		return sysOrganizationDao.count(specification);
	}


}
